package com.engine.jucailinkq.attendance.attendanceanalysis.cmd;

import com.alibaba.fastjson.JSONObject;
import com.engine.jucailinkq.attendance.attendanceanalysis.cmd.item.WorkOvertimeItemCmd;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.ShiftService;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.impl.ShiftServiceImpl;
import com.engine.jucailinkq.attendance.enums.CheckBoxEnum;
import com.engine.jucailinkq.attendance.enums.ClassBelongToEnum;
import com.engine.jucailinkq.attendance.enums.ClassSegmentTypeEnum;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.entity.BizLogContext;
import com.engine.jucailinkq.common.util.DateUtil;
import com.engine.jucailinkq.common.util.DbTools;
import com.engine.common.util.ServiceUtil;
import com.engine.jucailinkq.common.util.ExtensionClassHolder;
import com.engine.jucailinkq.common.util.Utils;
import com.engine.core.interceptor.CommandContext;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import weaver.general.BaseBean;
import weaver.general.Util;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 获得班次信息
 * !!!!!!!!!!!!!!!
 * ****这边改了代码，ShiftServiceImpl的getSchedulingInFormation方法打卡匹配班次类也得跟着变，里面有相同逻辑****
 *
 */
@Slf4j
public class GetScheduleResultListCmd extends AbstractCommonCommand<Map<String,Object>> {
    private ShiftService basicsetService = ServiceUtil.getService(ShiftServiceImpl.class);

    public GetScheduleResultListCmd(Map<String,Object> params){
        this.params=params;
    }
    @Override
    public BizLogContext getLogContext() {
        return null;
    }

    @Override
    public Map<String, Object> execute(CommandContext commandContext) {
        new BaseBean().writeLog("GetScheduleResultListCmd start.");
        /** 班次信息*/
        List<Map<String,Object>> attendanceItems = (List<Map<String,Object>>)params.get("attendanceItems");

        Map<String,Object> schedulingResultsMap = (Map<String,Object>)params.get("schedulingResultsMap");
        List<Map<String,Object>> schedulingResultsList = (List<Map<String,Object>>)schedulingResultsMap.get("data");

        Map<String,String> dateMap = schedulingResultsList.stream().collect(Collectors.toMap(e->Util.null2String(e.get("bcrq")),e->Util.null2String(e.get("rqlx"))));
        //去除候选班组
        List<Map<String,Object>> candidateSchedulingResultsList  = schedulingResultsList.stream().filter(e->!"".equals(Util.null2String(e.get("hxbz"))) && "".equals(Util.null2String(e.get("bcxx")))).collect(Collectors.toList());
        schedulingResultsList = schedulingResultsList.stream().filter(e->!"".equals(Util.null2String(e.get("bcxx")))).collect(Collectors.toList());

        Map<String,Object> schedulMap = Maps.newHashMap();

        try {
            String glpb = "";
            for (Map<String, Object> schedulingResult : schedulingResultsList) {
                glpb = Util.null2String(schedulingResult.get("pbgl"));
            }
            Map<String, List<Map<String, Object>>> schedulingMap = schedulingResultsList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("bcxx")).split("-")[0]));
            Map<String, List<Map<String, Object>>> schedulingMapBydate = schedulingResultsList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("bcrq"))));
            schedulMap.put("schedulingMapBydate", schedulingMapBydate);

            Map<String, List<Map<String, Object>>> resultMap = Maps.newHashMap();
            String sql = "select a.xxbdkzdjb,a.sfxx,a.id bcxx,a.edsc,a.zgzsc,a.bcsdxx,a.sfdx,a.sfkt,b.bdlx,a.btgz,a.fgsjd,a.zddxfz,a.dxhs,b.kssj dtkssj,b.jssj dtjssj,b.ksdk,b.jsdk,b.tqdkfzs,b.thdkfzs,b.edxss,b.edfzs,b.edts,b.sfdx dtsfdx,b.zddxfz dtzddxfz,b.dxhs dtdxhs,b.gsrq from uf_jcl_kq_bcxx a left join uf_jcl_kq_bcxx_dt1 b on a.id=b.mainid where a.id in (";
            String bcxxIds = "";
            for (Map.Entry<String, List<Map<String, Object>>> entry : schedulingMap.entrySet()) {
                if (!entry.getKey().equals("")) {
                    bcxxIds += entry.getKey() + ",";
                }
            }
            List<Map<String, Object>> dataList = Lists.newArrayList();
            if (!"".equals(bcxxIds)) {
                bcxxIds = bcxxIds.substring(0, bcxxIds.length() - 1);
                sql = sql + bcxxIds + ") order by b.gsrq,b.kssj";
                dataList = DbTools.getSqlToList(sql);
                Map<String, List<Map<String, Object>>> dataMap = dataList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("bcxx"))));

                List<Map<String, Object>> finalAttendanceItems = attendanceItems;
                dataMap.entrySet().forEach(e -> {
                    List<Map<String, Object>> schedulingList = schedulingMap.get(e.getKey());
                    List<Map<String, Object>> bcxxs = e.getValue();
                    for (Map<String, Object> scheduling : schedulingList) {
                        String bcrq = Util.null2String(scheduling.get("bcrq"));
                        String rqlx = Util.null2String(scheduling.get("rqlx"));
                        String sfxx = Util.null2String(scheduling.get("sfxx"));
                        List<Map<String, Object>> classs = Lists.newArrayList();
                        for (Map<String, Object> map : bcxxs) {
                            Map<String, Object> newMap = Maps.newHashMap();
                            newMap.putAll(map);
                            newMap.put("rqlx", rqlx);
                            if (!newMap.get("sfxx").equals(CheckBoxEnum.CHECKED.getKey())) {
                                newMap.put("sfxx", sfxx);
                            }
                            adjustWorkOverTimeClass(newMap, finalAttendanceItems, commandContext);
                            classs.add(newMap);
                        }
                        resultMap.put(bcrq, classs);
                    }
                });
            }

            /**
             * 候选班组
             */
            Map<String, Object> clockInTimeDataMap = Maps.newHashMap();
            for (Map<String, Object> candidateSchedulingResult : candidateSchedulingResultsList) {
                Map<String, Object> shiftResult = basicsetService.punchMatchShift(params.get("pbdx").toString(), candidateSchedulingResult, (List<Map<String, Object>>) params.get("clockInData"), (Map<String, Map<String, Object>>) params.get("clockInTimeMap"));
                List<Map<String, Object>> bcData = (List<Map<String, Object>>) shiftResult.get("bcData");
                for (Map<String, Object> data : bcData) {
                    adjustWorkOverTimeClass(data, attendanceItems, commandContext);
                }
                resultMap.put(shiftResult.get("bcrq").toString(), bcData);
                clockInTimeDataMap.put(shiftResult.get("bcrq").toString(), shiftResult.get("clockInTimeData"));
            }

            /** 加班计划*/
            sql = "select a.id,b.jbry,b.ksrq,b.kssj,b.jblx,b.jsrq,b.jssj,b.jbsc,b.gsrq from uf_jcl_kq_jbjh a left join uf_jcl_kq_jbjh_dt1 b on a.id=b.mainid where b.jbry =? and b.gsrq>=? and b.gsrq<=? and (b.jbcx=0 or b.jbcx is null) and a.jlzt=1";
            Map<String, List<Map<String, Object>>> overtimePlanMap = DbTools.getSqlToList(sql, params.get("pbdx"), params.get("startDate"), params.get("endDate")).stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("gsrq"))));

            //考勤项目
            for (Map.Entry<String, List<Map<String, Object>>> e : overtimePlanMap.entrySet()) {
                if (resultMap.get(e.getKey()) == null) {
                    resultMap.put(e.getKey(), Lists.newArrayList());
                }
                List<Map<String, Object>> resultList = resultMap.get(e.getKey());
                List<Map<String, Object>> schedulingdateMap = schedulingMapBydate.get(e.getKey());
                List<Map<String, Object>> overtimePlanList = e.getValue();
                for (Map<String, Object> overtimePlan : overtimePlanList) {
                    Map<String, Object> map = Maps.newHashMap();
                    if (!overtimePlan.get("ksrq").equals(overtimePlan.get("jsrq"))) {
                        map.put("sfkt", "1");
                    } else {
                        map.put("sfkt", "0");
                    }
                    //查找对应的考勤项目
                    String querySql = "select a.id keyid,a.* from uf_jcl_kq_kqxm a where id=?";
                    List<Map<String, Object>> overPlanattendanceItems = DbTools.getSqlToList(querySql, overtimePlan.get("jblx"));


                    map.put("bcxx", resultList == null || resultList.size() == 0 || resultList.get(0) == null ? "" : resultList.get(0).get("bcxx"));
                    map.put("bcsdxx", resultList == null || resultList.size() == 0 || resultList.get(0) == null ? "" : resultList.get(0).get("bcsdxx"));
                    if (resultList.size() > 0) {
                        map.putAll(resultList.get(0));
                        map.put("sfxx", Util.null2String(resultList.get(0).get("sfxx")));
                    } else {
                        map.put("edsc", "0");
                        if (schedulingdateMap != null && schedulingdateMap.size() > 0) {
                            map.put("sfxx", Util.null2String(schedulingdateMap.get(0).get("sfxx")));
                        }
                    }
                    map.put("edts", "0");
                    map.put("bdlx", ClassSegmentTypeEnum.OVERTIME_PLAN.getKey());
                    map.put("dtkssj", overtimePlan.get("kssj"));
                    map.put("dtjssj", overtimePlan.get("jssj"));
                    map.put("ksdk", "0");
                    map.put("jsdk", "0");
                    map.put("overtimePlanId", overtimePlan.get("id"));
                    map.put("tqdkfzs", ExtensionClassHolder.getGlobalSetMap().get("defaultClockRange") == null ? "60" : ExtensionClassHolder.getGlobalSetMap().get("defaultClockRange"));
                    map.put("thdkfzs", ExtensionClassHolder.getGlobalSetMap().get("defaultClockRange") == null ? "60" : ExtensionClassHolder.getGlobalSetMap().get("defaultClockRange"));
                    map.put("rqlx", dateMap.get(e.getKey()));
                    map.put("edxss", overtimePlan.get("jbsc"));
                    map.put("edfzs", Double.valueOf(overtimePlan.get("jbsc").toString()) * 60);

                    map.put("jblx", overPlanattendanceItems);
                    if (DateUtil.getTime(overtimePlan.get("ksrq").toString()).compareTo(DateUtil.getTime(e.getKey())) < 0) {
                        map.put("gsrq", ClassBelongToEnum.YESTERDAY.getKey());
                    } else if (DateUtil.getTime(overtimePlan.get("ksrq").toString()).compareTo(DateUtil.getTime(e.getKey())) == 0) {
                        map.put("gsrq", ClassBelongToEnum.NOWDAY.getKey());
                    } else if (DateUtil.getTime(overtimePlan.get("ksrq").toString()).compareTo(DateUtil.getTime(e.getKey())) > 0) {
                        map.put("gsrq", ClassBelongToEnum.NEXTDAY.getKey());
                    }
                    if (overPlanattendanceItems.size() > 0) {
                        map.put("ksdk", overPlanattendanceItems.get(0).get("ksjbbxydk"));
                        map.put("jsdk", overPlanattendanceItems.get(0).get("jsjbbxydk"));
                        map.put("tqdkfzs", overPlanattendanceItems.get(0).get("tqdkyxfzs"));
                        map.put("thdkfzs", overPlanattendanceItems.get(0).get("thdkyxfzs"));
                        map.put("jbwdhlfzs", overPlanattendanceItems.get(0).get("jbwdhlfzs"));
                        map.put("jbzzhlfzs", overPlanattendanceItems.get(0).get("jbzzhlfzs"));
                    }
                    if (resultList.size() > 0) {
                        String kssjbegin = Utils.getkssjTime(resultList.get(0), e.getKey());
                        String kssjend = Utils.getkssjTime(resultList.get(resultList.size() - 1), e.getKey());
                        String kssj = overtimePlan.get("ksrq") + " " + overtimePlan.get("kssj");
                        if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(kssjbegin)) < 0) {
                            //加班计划在开头
                            resultList.add(0, map);
                        } else if (DateUtil.getTime(kssj).compareTo(DateUtil.getTime(kssjend)) > 0) {
                            //加班计划在末尾
                            resultList.add(map);
                        } else {
                            if (resultList.size() > 1) {
                                //加班计划在中间
                                for (int j = 1; j < resultList.size(); j++) {
                                    String kssj1 = Utils.getkssjTime(resultList.get(j), e.getKey());
                                    String kssj2 = overtimePlan.get("ksrq") + " " + overtimePlan.get("kssj");
                                    String kssj3 = Utils.getkssjTime(resultList.get(j - 1), e.getKey());
                                    if (DateUtil.getTime(kssj1).compareTo(DateUtil.getTime(kssj2)) >= 0 && DateUtil.getTime(kssj3).compareTo(DateUtil.getTime(kssj2)) <= 0) {
                                        resultList.add(j, map);
                                        break;
                                    }
                                }
                            }
                        }
                    } else {
                        resultList.add(map);
                    }
                }
            }

            schedulMap.put("schedulingResultsMap", resultMap);
            schedulMap.put("clockInTimeDataMap", clockInTimeDataMap);
            log.debug("SchedulingResults : [{}]", schedulMap);
        } catch (Exception e) {
            new BaseBean().writeLog("GetScheduleResultListCmd error:" + e.getMessage());
        }
        return schedulMap;
    }

    public List<Map<String,Object>> getDate(Map<String,Object> param){
        String userId = params.get("pbdx").toString();
        String nd = Util.null2String(param.get("nd"));
        String glpb = Util.null2String(param.get("glpb"));
        String sql = "select nd,rq,nlrq,rqlx,xq,rlmc from uf_jcl_kq_rlxx a left join uf_jcl_kq_glpb  b on a.rlmc=b.qyrl where b.id=? and a.nd=? ";
        List<Map<String,Object>> dataList=null;
        if ("".equals(glpb)){
            sql = "select subcompanyid1 from hrmresource where id =?";
            Map<String,Object> departMentMap = DbTools.getSqlToMap(sql,userId);
            String subcompanyid1 = departMentMap.get("subcompanyid1").toString();
            dataList = Utils.getDefaultDateList(subcompanyid1,nd);
        }else {
            dataList = DbTools.getSqlToList(sql,glpb,nd);
        }
        return dataList;
    }

    /**
     * 1、调整加班时段的推前和推后的打卡时间，以最大值为准
     * 2、当为休息班次且休息班打卡自动加班时，将工作时段转为加班计划
     * @param scheduleMap
     */
    public void  adjustWorkOverTimeClass(Map<String,Object> scheduleMap,List<Map<String,Object>> attendanceItems,CommandContext commandContext){
        String bdlx = Util.null2String(scheduleMap.get("bdlx"));
        //是否休息
        String sfxx = Util.null2String(scheduleMap.get("sfxx"));
        //休息班打卡自动加班
        String xxbdkzdjb = Util.null2String(scheduleMap.get("xxbdkzdjb"));
        if (CheckBoxEnum.CHECKED.getKey().equals(sfxx) && CheckBoxEnum.CHECKED.getKey().equals(xxbdkzdjb) &&
                bdlx.equals(ClassSegmentTypeEnum.WORK_TIME.getKey())){
            scheduleMap.put("beforeClassSegment",bdlx);
            scheduleMap.put("bdlx",ClassSegmentTypeEnum.OVERTIME_PLAN.getKey());
            bdlx = ClassSegmentTypeEnum.OVERTIME_PLAN.getKey();
        }

        if (Utils.ifOverTimeClassSegment(scheduleMap.get("bdlx").toString())){
            Map<String,Object> getWorkOverTimeParam = Maps.newHashMap();
            getWorkOverTimeParam.put("attendanceItems",attendanceItems);
            getWorkOverTimeParam.put("rqlx",scheduleMap.get("rqlx"));
            getWorkOverTimeParam.put("workfor", Utils.getWorkFor(bdlx));
            List<Map<String,Object>> workTimeBeItems = Lists.newArrayList();

            if (ClassSegmentTypeEnum.EXTENDED_OVERTIME.getKey().equals(bdlx)){
                Map<String,Object> result = new WorkOvertimeItemCmd(getWorkOverTimeParam).execute(commandContext);
                //加班项目
                workTimeBeItems = (List<Map<String,Object>>)result.get("attendanceItems");
            }else if (ClassSegmentTypeEnum.EARLY_OVERTIME.getKey().equals(bdlx)){
                Map<String,Object> result = new WorkOvertimeItemCmd(getWorkOverTimeParam).execute(commandContext);
                workTimeBeItems = (List<Map<String,Object>>)result.get("attendanceItems");
            }else if (ClassSegmentTypeEnum.OVERTIME_PLAN.getKey().equals(bdlx) &&
                    ClassSegmentTypeEnum.WORK_TIME.getKey().equals(scheduleMap.get("beforeClassSegment"))){
                Map<String,Object> result = new WorkOvertimeItemCmd(getWorkOverTimeParam).execute(commandContext);
                workTimeBeItems = (List<Map<String,Object>>)result.get("attendanceItems");
                scheduleMap.put("jblx",workTimeBeItems);
            }else if (ClassSegmentTypeEnum.OVERTIME_IN_CLASS.getKey().equals(bdlx)){
                Map<String,Object> result = new WorkOvertimeItemCmd(getWorkOverTimeParam).execute(commandContext);
                workTimeBeItems = (List<Map<String,Object>>)result.get("attendanceItems");
            }
            if (workTimeBeItems.size() > 0){
                int tqdkfzs = Integer.valueOf(Util.null2String(scheduleMap.get("tqdkfzs")).equals("")?"0":Util.null2String(scheduleMap.get("tqdkfzs")));
                int thdkfzs = Integer.valueOf(Util.null2String(scheduleMap.get("thdkfzs")).equals("")?"0":Util.null2String(scheduleMap.get("thdkfzs")));
                int tqdkyxfzs = Util.null2String(workTimeBeItems.get(0).get("tqdkyxfzs")).equals("")?0:Integer.valueOf(Util.null2String(workTimeBeItems.get(0).get("tqdkyxfzs")));
                int thdkyxfzs = Util.null2String(workTimeBeItems.get(0).get("thdkyxfzs")).equals("")?0:Integer.valueOf(Util.null2String(workTimeBeItems.get(0).get("thdkyxfzs")));

                if (tqdkyxfzs > tqdkfzs){
                    //提前打卡分钟数
                    scheduleMap.put("tqdkfzs",tqdkyxfzs);
                }
                if (thdkyxfzs > thdkfzs){
                    //推后打卡分钟数
                    scheduleMap.put("thdkfzs",thdkyxfzs);
                }
            }
        }
    }



}
